package main

import (
	"bytes"
	"io"
	"log"
	"net/http"

	jsoniter "github.com/json-iterator/go"
)

type outputLogLine struct {
	DebugType string      `json:"debug_type"`
	Method    string      `json:"method"`
	Host      string      `json:"host"`
	Path      string      `json:"path"`
	Scheme    string      `json:"scheme"`
	Header    http.Header `json:"header"`
	Body      string      `json:"body"`
}

func handleRoot(w http.ResponseWriter, r *http.Request) {
	var json = jsoniter.ConfigCompatibleWithStandardLibrary
	log.SetFlags(log.Lshortfile | log.LstdFlags)
	r.ParseForm()

	// Output http request log
	reqOut := new(outputLogLine)
	reqOut.DebugType = "REQUEST"
	reqOut.Method = r.Method
	reqOut.Host = r.Host
	reqOut.Path = r.URL.Path
	reqOut.Scheme = r.URL.Scheme
	reqOut.Header = r.Header
	reqBody, err := io.ReadAll(r.Body)
	defer r.Body.Close()
	if err != nil {
		log.Println("HTTP_REQUEST_TEST:", err)
	}
	reqOut.Body = string(reqBody)

	jsonReq, err := json.Marshal(reqOut)
	if err != nil {
		log.Println("HTTP_REQUEST_TEST:", err)
	}

	log.Println(string(jsonReq))
	if len(reqBody) != 0 {
		log.Println("REQUEST_BODY:\n" + string(reqBody))
	}

	// Request to next server
	c := &http.Client{}
	newR, err := http.NewRequest(r.Method, backend+r.URL.Path, bytes.NewBuffer(reqBody))
	if err != nil {
		log.Println("HTTP_REQUEST_TEST:", err)
	}
	newR.Header = r.Header
	resp, err := c.Do(newR)
	if err != nil {
		log.Println("HTTP_REQUEST_TEST:", err)
	}

	// Output http response log
	respOut := new(outputLogLine)
	respOut.DebugType = "RESPONSE"
	respOut.Method = resp.Request.Method
	respOut.Host = resp.Request.Host
	respOut.Path = resp.Request.URL.Path
	respOut.Scheme = resp.Request.URL.Scheme
	respOut.Header = resp.Header
	respBody, err := io.ReadAll(resp.Body)
	defer r.Body.Close()
	if err != nil {
		log.Println("HTTP_REQUEST_TEST:", err)
	}
	respOut.Body = string(respBody)

	jsonResp, err := json.Marshal(respOut)
	if err != nil {
		log.Println("HTTP_REQUEST_TEST:", err)
	}

	log.Println(string(jsonResp))
	if len(respBody) != 0 {
		log.Println("RESPONSE_BODY:\n" + string(respBody))
	}

	// Write response to http.ResponseWriter
	for k, v := range resp.Header {
		if k == "Content-Length" {
			continue
		}
		for _, vv := range v {
			w.Header().Add(k, vv)
		}
	}
	w.Write(respBody)
}
